<template>
  <div :class="$style.page">
    <div :class="$style.container" ref="containerRef"></div>

    <el-button type="primary">primary</el-button>
    <el-button type="danger">danger</el-button>
    <el-button type="success">success</el-button>

    <!-- 加载 -->
    <t-loading
      v-model="progress.show"
      :progress="progress.percentage"
      :bg-src="__CONFOG__.bgSrc"
      :zindex="1"
    ></t-loading>
  </div>
</template>

<script lang="ts" setup>
import tLoading from '@/components/loading/index.vue'

import { Scene } from './class.ts'
import { getPageOpts } from './data'
import { request } from '@/api'

import * as MS from './data/methods'
import { useSky } from '@/hooks/sky'
import { useResize } from '@/hooks/scene-resize'

import __CONFOG__ from './data/config'
import type { ObjectItem } from 'three-scene/types/model.d.ts'

const { Hooks, Utils } = MS

// 界面配置
const pageOpts = reactive(getPageOpts())
const options: ConstructorParameters<typeof Scene>[0] = {
  baseUrl: __CONFOG__.baseUrl,
  // cruise: pageOpts.cruise,
  // env: __CONFOG__.env,
  render: {
    alpha: true
  },
  controls: {
    enableDamping: true,
    dampingFactor: 0.48,
    maxPolarAngle: Math.PI * 0.48,
    screenSpacePanning: false,
    maxDistance: 800
  },
  camera: {
    near: 1e-10,
    fov: 52,
    position: [0, 3200, 4290]
  },
  ambientLight: {
    intensity: 2
  },
  directionalLight: {
    light2: false,
    intensity: 2.5,
    position: [0, 7000, 0],
    position2: [0, 7000, -2000],
    shadow: {
      mapSize: 512 * 4
    },
    shadowCamera: {
      boundary: 7000
    }
  },
  grid: {
    visible: !true,
    // fork: true,
    gridColor: 0x48fff1,
    forkColor: 0x48fff1
  }
}
let scene: InstanceType<typeof Scene>
const container = useTemplateRef('containerRef')

const gitOssBase = import.meta.env.VITE_GIT_OSS

const { skys } = useSky()
const { backgroundLoad } = Hooks.useBackground(gitOssBase + '/sky/', skys)

const { progress, loadModels, getModel, initModels } = Hooks.useModelLoader({
  baseUrl: __CONFOG__.baseUrl,
  indexDB: __CONFOG__.indexDB
})

// 模型配置列表
const modelConfigList = ref<ObjectItem[]>([])

// 初始化场景模型
const initSceneModel = () => {
  loadModels(pageOpts.models, () => {
    request.d3.getHotel().then(res => {
      let json: any = {}
      if (res.ConfigJson instanceof Object) {
        json = res.ConfigJson
      } else if (typeof res.ConfigJson == 'string') {
        try {
          json = JSON.parse(res.ConfigJson)
        } catch (er) {}
      }
      modelConfigList.value = res.JsonList

      // 巡航点位
      pageOpts.cruise.points = json.cruise || []
      // 漫游点位
      pageOpts.roamPoints = json.roamPoints || []

      // 配置
      Object.keys(json).forEach(key => {
        // @ts-ignore
        pageOpts.config && (pageOpts.config[key] = json[key])
      })

      setTimeout(() => {
        loadScene()
      }, 100)
    })
  })
}

// 加载场景
const loadScene = async () => {
  //  组装场景
  await assemblyScenario()

  scene?.addWater()
}

// 组装场景
const assemblyScenario = async () => {
  // 清除
  scene.clearBuilding()

  await nextTick()
  await initModels(modelConfigList.value, loopLoadObject)

  // 巡航
  scene.setCruisePoint(pageOpts.cruise.points || [])

  const to = scene.getValidTargetPosition(pageOpts.config || {})
  scene.camera.position.set(to.x, to.y, to.z)
  // 加载进度 100
  progress.percentage = 100
  progress.show = false
  scene.controlSave()
}

// 循环加载对象
const loopLoadObject = async (item: ObjectItem) => {
  if (!item) return
  const { type } = item

  const obj = getModel(type)
  if (!obj) {
    // 点位
    return
  }

  const { anchorType = [], animationModelType = [] } = pageOpts

  // 深克隆
  let model = Utils.modelDeepClone(obj)
  const { position: POS, scale: SCA, rotation: ROT } = Utils.get_P_S_R_param(model, item)
  const [x, y, z] = POS

  // 缩放
  model.scale.set(...SCA)

  // 摆放位置
  model.position.set(x, y, z)
  // 转换方位
  model.rotation.set(...ROT)

  model._isBuilding_ = true
  model.data = item

  // 动画
  if (animationModelType.includes(type)) {
    scene.addModelAnimate(model, obj.animations, true, 1)
  }

  // 记录备用坐标(更随标记)
  if (item.followMark || item.mark) {
    model._position_ = { x, y, z }
  }

  // 锚点
  if (anchorType.includes(type)) {
    model._isAnchor_ = true
  } else {
    scene.addBuilding(model)
  }

  return Promise.resolve()
}

const initPage = () => {
  options.container = container.value as HTMLElement

  scene = new Scene(options).run()

  useResize(scene).resize()

  initSceneModel()
  backgroundLoad(scene, __CONFOG__.skyCode)

  // onListen(scene)
}

onMounted(initPage)
</script>

<style lang="scss" module>
@use './style.scss';
</style>
